package pl.register.android.activities.correlation.logic;

import android.app.ProgressDialog;
import android.content.Context;
import android.util.Log;
import android.widget.Toast;
import pl.register.android.activities.correlation.ui.CorrelationView;
import pl.register.android.course.Course;
import pl.register.android.database.DatabaseAdapter;
import pl.register.android.database.dao.*;
import pl.register.android.database.exception.NotFoundCourseException;
import pl.register.android.group.StudentsGroup;
import pl.register.android.lesson.TagLesson;
import pl.register.android.preferences.ResotorePreferences;
import pl.register.android.program.Program;
import pl.register.android.student.Student;
import pl.register.android.year.Year;
import pl.register.android.year.YearType;
import roboguice.util.RoboAsyncTask;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AsyncCorrelationLoader extends RoboAsyncTask<List<Correlation>> {
    private static final String TAG = AsyncCorrelationLoader.class.getSimpleName();

    private CourseDao courseDao;

    private YearDao yearDao;

    private StudentGroupDao groupDao;

    private ProgramDao programDao;

    private StudentsDao studentsDao;


    private ProgressDialog progressDialog;

    private CorrelationStudentsPresenter presenter;

    private CorrelationView view;

    private Course courseToRestore;

    public AsyncCorrelationLoader(Context context, CorrelationView view, CorrelationStudentsPresenter presenter, Course courseToRestore) {
        super(context);
        this.view = view;
        this.presenter = presenter;
        this.courseToRestore = courseToRestore;

        DatabaseAdapter dbAdapter = presenter.getDatabaseAdapter();
        courseDao = dbAdapter.getCourseDao();
        yearDao = dbAdapter.getStudentYearDao();
        groupDao = dbAdapter.getStudentGroupDao();
        studentsDao = dbAdapter.getStudentDao();
        programDao = dbAdapter.getProgramDao();

        progressDialog = new ProgressDialog(context);
        progressDialog.setCancelable(false);
        progressDialog.setIndeterminate(true);
        progressDialog.setMessage("Inicjalizacja zestawienia. Proszę czekać...");
    }

    @Override
    protected void onPreExecute() {
        progressDialog.show();
    }

    @Override
    public List<Correlation> call() throws Exception {
        Course course = courseDao.findCourseFor(courseToRestore.getStartYear(), courseToRestore.getEndYear());
        List<Year> years = findYearsWithProgram(course);

        List<Correlation> correlations = new ArrayList<Correlation>();
        for (Year year : years) {
            List<StudentsGroup> groups = findGroupsWithStudents(course, year);
            correlations.add(createCorrelation(year, groups));
        }

        presenter.initWith(course);
        ResotorePreferences.saveCourse(context, course);
        return correlations;
    }

    private List<Year> findYearsWithProgram(Course course) {
        List<Year> studentYears = yearDao.findYearsBy(course);
        for (Year year : studentYears) {
            Program program = programDao.findProgramFor(year);
            year.setProgram(program);
        }
        return studentYears;
    }

    private List<StudentsGroup> findGroupsWithStudents(Course course, Year year) {
        List<StudentsGroup> groups = groupDao.findGroupsBy(year);
        for (StudentsGroup group : groups) {
            List<Student> students = studentsDao.findStudentsBy(group, course);
            group.setStudents(students);
        }
        return groups;
    }

    private Correlation createCorrelation(Year year, List<StudentsGroup> groups) {
        Map<TagLesson, Program> programMap = new HashMap<TagLesson, Program>();
        for (TagLesson tag : TagLesson.asList()) {
            Program program = programDao.findProgramForGroupBy(groups.get(0), tag);
            programMap.put(tag, program);
        }
        return new Correlation(year, groups, programMap);
    }

    @Override
    protected void onSuccess(List<Correlation> result) {
        TagLesson selectedTagLesson = ResotorePreferences.getTag(context);
        YearType selectedYearType = ResotorePreferences.getCorrelationYearType(context);
        presenter.populateViews(selectedTagLesson, result, selectedYearType);
    }

    @Override
    protected void onFinally() {
        if (progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
    }

    @Override
    protected void onException(Exception exception) {
        try {
            throw exception;
        } catch (NotFoundCourseException e) {
            view.showLoadLastCourseDialog(courseToRestore);
        } catch (Exception e1) {
            Toast.makeText(getContext(), "Wystąpił nieoczekiwany problem podczas zczytywania danch.", Toast.LENGTH_SHORT).show();
            e1.printStackTrace();
        }
        Log.e(TAG, exception.getMessage(), exception);
    }

}